package com.ampas.mist;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.aisid.artesia.mist.CreateAssetsHandler;
import com.artesia.common.exception.BaseTeamsException;
import com.artesia.security.SecuritySession;
import com.artesia.security.session.services.AuthenticationServices;


public class IngestMonitor {

	private static Logger LOG = Logger.getLogger( com.ampas.mist.IngestMonitor.class );
	
	private ClassPathXmlApplicationContext appContext = null;
	private Map < String, String > promptValueMap = null;
	private String mistDirectoryRoot = null;
	private String attemptedDirectoryRoot = null;
	private String mistUser = null;
	private String mistPass = null;
	
	public IngestMonitor() {
		try {
		
			appContext = new ClassPathXmlApplicationContext(
					new String[] { "mistAutoIngest.xml" });
			promptValueMap = (Map<String, String>) appContext.getBean( "promptValueMap" );
			mistDirectoryRoot = ( String ) appContext.getBean( "mistDirectoryRoot" );
			attemptedDirectoryRoot = ( String ) appContext.getBean( "attemptedDirectoryRoot" );
			mistUser = ( String ) appContext.getBean( "mistUser" );
			mistPass = ( String ) appContext.getBean( "mistPass" );

			SecuritySession session = null;
			try {
				session = AuthenticationServices.getInstance().login(mistUser, mistPass);
			} catch (BaseTeamsException e) {
				e.printStackTrace();
				System.exit(0);
			}
			List < File > files = checkForFiles( mistDirectoryRoot );
//			writeSpreadSheet( mistDirectoryRoot, files );
			HSSFSheet sheet = createSpreadsheet( files );
			submitMistRequest(sheet, session);
			moveFiles(files, attemptedDirectoryRoot);
			
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private List < File > checkForFiles ( String root ) throws IOException
	{
		Iterator < File > files = FileUtils.iterateFiles( new File ( root ), null, true );
		
		List < File > fileList = new ArrayList < File > ();
		while ( files.hasNext() )
		{
			fileList.add( files.next() );
		}
		
		return fileList;
	}
	
	private void writeSpreadSheet( String rootPath, List < File > fileList )  throws IOException
	{

		OutputStream stream = new FileOutputStream(rootPath + "/file.xls");

		HSSFWorkbook workbook = createWorkbook(fileList);
		workbook.write(stream);

		stream.flush();
		stream.close();
	}
	
	private boolean isAssetFile(File file) {
		if (file.isFile()) {
			String fileName = file.getName();

			// compare file extension to list stored in spring config

		}

		return true;
	}

	private HSSFSheet createSpreadsheet(List<File> assetFiles) {

		HSSFWorkbook workbook = createWorkbook( assetFiles );

		return workbook.getSheetAt( 0 );
	}

	private void moveFiles ( List < File > files, String rootDestination ) throws IOException
	{

		for (File file : files) 
		{
			String srcFilePath = file.getAbsolutePath();
			String attemptedFilePath = srcFilePath.replaceAll(mistDirectoryRoot, rootDestination);

			FileUtils.copyFile(file, new File ( attemptedFilePath ) );
			
		}
		
	}
	
	private HSSFWorkbook createWorkbook(List<File> assetFiles) {

		HSSFWorkbook mistSpreadsheet = new HSSFWorkbook();
		HSSFSheet sheet = mistSpreadsheet.createSheet();

		addHeaderRow(sheet);

		short row = 1;
		for (int i = 0; i < assetFiles.size(); i++) {

			File assetFile = assetFiles.get(i);
			if (isAssetFile(assetFile)) {
				addDataRow(sheet, assetFile, row);
				row++;
			}

		}

		return mistSpreadsheet;
	}

	private HSSFSheet addHeaderRow(HSSFSheet sheet) {
		// get header rows from spring config
		HSSFRow row = sheet.createRow(0);

		Set < String > prompts = promptValueMap.keySet();
		Iterator< String > cells =  prompts.iterator();
		for (short i = 0; cells.hasNext(); i++) {
			
			String cellVal = cells.next();
			System.out.println("Adding header cell");
			HSSFCell cell = row.createCell(i);
			cell.setCellValue( cellVal );

		}
		return sheet;
	}

	private HSSFSheet addDataRow(HSSFSheet sheet, File file, short rowNum) {
		// get default data rows from spring config
		HSSFRow row = sheet.createRow(rowNum);
		
		Set < String > prompts = promptValueMap.keySet();
		Iterator< String > cells =  prompts.iterator();
		
		for (short i = 0; cells.hasNext(); i++) {

			String promptVal = cells.next();
			String value = promptValueMap.get( promptVal );
			
			String cellVal = "";
			if ( value.equals( "$filepath" ))
			{
				cellVal = file.getAbsolutePath();
			}
			else if ( value.equals( "$increment" ))
			{
				cellVal = String.valueOf( rowNum );
			}
			else if ( value.startsWith( "$dir" ))
			{
				int depth = Integer.parseInt( value.substring( 4 ) );
				System.out.println( "depth = " + depth );
				String path = file.getAbsolutePath();
				String[] dirs = path.split( "/" );
				for (int j = 0; j < dirs.length; j++) {
					System.out.println( j + " = " + dirs[j] );
				}
				
				if ( dirs.length >= depth )
				{
					cellVal = dirs [ depth ];
				}
				
			}
			else if ( !promptVal.equals( "" ) )
			{
				cellVal = value;
			}

			System.out.println("Adding data cell");
			HSSFCell cell = row.createCell(i);
			cell.setCellValue( cellVal );

		}
		System.out.println( "called add row ");
		return sheet;
	}

	private void submitMistRequest ( HSSFSheet sheet, SecuritySession session )
	{

		String manifestJobName = session.getLoginName()+"-"+new Date().getTime();;
		
		CreateAssetsHandler handler = new CreateAssetsHandler( manifestJobName, sheet, session );
		
		handler.run();
		
	}

	public static void main(String[] args) {

		new IngestMonitor();

	}

}
